// 版权归Go作者所有。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

// 此文件实现了对iimport的支持功能。去

package gcimporter

import (
	"fmt"
	"go/token"
	"go/types"
	"sync"
)

func errorf(format string, args ...any) {
	panic(fmt.Sprintf(format, args...))
}

// deltaNewFile是表示新文件的幻线增量偏移量。
// 我们使用-64是因为它很少见；见第20080期和第41619条。
// /-64是一个字节中作为变量的最小整数。
const deltaNewFile = -64

// 合成一个令牌。Pos 
type fakeFileSet struct {
	fset  *token.FileSet
	files map[string]*fileInfo
}

type fileInfo struct {
	file     *token.File
	lastline int
}

const maxlines = 64 * 1024

func (s *fakeFileSet) pos(file string, line, column int) token.Pos {
	// TODO（mdempsky）：使用列。

	// 由于我们不知道所需的文件位置集，因此我们保留每个文件的最大行位置。我们延迟呼叫令牌。文件设置行直到
	// 所有位置都已计算（通过fakeFileSet.SetLines），因此
	// 我们可以避免设置不必要的行。另见golang/go#46586。
	f := s.files[file]
	if f == nil {
		f = &fileInfo{file: s.fset.AddFile(file, -1, maxlines)}
		s.files[file] = f
	}

	if line > maxlines {
		line = 1
	}
	if line > f.lastline {
		f.lastline = line
	}

	// 假设f.file只包含换行符，则返回一个假位置。
	return token.Pos(f.file.Base() + line - 1)
}

func (s *fakeFileSet) setLines() {
	fakeLinesOnce.Do(func() {
		fakeLines = make([]int, maxlines)
		for i := range fakeLines {
			fakeLines[i] = i
		}
	})
	for _, f := range s.files {
		f.file.SetLines(fakeLines[:f.lastline])
	}
}

var (
	fakeLines     []int
	fakeLinesOnce sync.Once
)

func chanDir(d int) types.ChanDir {
	// 标记值必须与cmd/compile/internal/gc/go中的常量匹配。go 
	switch d {
	case 1 /* Crecv */ :
		return types.RecvOnly
	case 2 /* Csend */ :
		return types.SendOnly
	case 3 /* Cboth */ :
		return types.SendRecv
	default:
		errorf("unexpected channel dir %d", d)
		return 0
	}
}

var predeclared = []types.Type{
	// 基本类型
	types.Typ[types.Bool],
	types.Typ[types.Int],
	types.Typ[types.Int8],
	types.Typ[types.Int16],
	types.Typ[types.Int32],
	types.Typ[types.Int64],
	types.Typ[types.Uint],
	types.Typ[types.Uint8],
	types.Typ[types.Uint16],
	types.Typ[types.Uint32],
	types.Typ[types.Uint64],
	types.Typ[types.Uintptr],
	types.Typ[types.Float32],
	types.Typ[types.Float64],
	types.Typ[types.Complex64],
	types.Typ[types.Complex128],
	types.Typ[types.String],

	// 基本类型别名
	types.Universe.Lookup("byte").Type(),
	types.Universe.Lookup("rune").Type(),

	// 错误
	types.Universe.Lookup("error").Type(),

	// 非类型
	types.Typ[types.UntypedBool],
	types.Typ[types.UntypedInt],
	types.Typ[types.UntypedRune],
	types.Typ[types.UntypedFloat],
	types.Typ[types.UntypedComplex],
	types.Typ[types.UntypedString],
	types.Typ[types.UntypedNil],

	// 包不安全
	types.Typ[types.UnsafePointer],

	// 无效类型
	types.Typ[types.Invalid], // 仅出现在有错误

	// 由gc内部使用的包中；本包装或包装中从未使用过。a文件
	// 不要与宇宙混淆任何
	anyType{},

	// 可比
	types.Universe.Lookup("comparable").Type(),

	// 任何
	types.Universe.Lookup("any").Type(),
}

type anyType struct{}

func (t anyType) Underlying() types.Type { return t }
func (t anyType) String() string         { return "any" }
